
var SpaceReg = /\s+/g
var TrimReg = /(^|,)\s+|\s+($)/g; //前空格，逗号后的空格; 后空格

module.exports = function Extractor(options) {
    var themeColor = options;
    var matchColorRegs = Object.keys(themeColor).map(c => new RegExp(`([\\s,:,"])(${c})([;,\\s,"])`, 'ig'));
    
    this.extractColors = function (src) {
        let cssEndIndex = 0;
        let ret = []
        let nameStart, nameEnd, cssEnd = -1;
        while (true) {
            nameStart = cssEnd + 1;
            nameEnd = src.indexOf('{', nameStart);
            cssEnd = findCssEnd(src, nameEnd);
            if (cssEnd > -1 && cssEnd > nameEnd && nameEnd > nameStart) {
                let cssCode = src.slice(nameEnd + 1, cssEnd);
                let rules;
                if (cssCode.indexOf('{') > -1) {
                    // @keyframes
                    rules = this.extractColors(cssCode);
                } else {
                    rules = this.getRules(cssCode)
                }

                if (Array.isArray(rules) && rules.length) {
                    let selector = src.slice(nameStart, nameEnd);
                    selector = selector.replace(TrimReg, '$1');
                    selector = selector.replace(SpaceReg, ' ');
                    let p = selector.indexOf(';');
                    if (p > -1) {
                        selector = selector.slice(p + 1);
                    }
                    let darkRules = [];
                    let nightRules = [];
                    // console.log(rules);
                    rules.forEach(rule => {
                        var key = Object.keys(rule)[0];
                        darkRules.push(rule[key].replace(key, themeColor[key].dark));
                    });
                    if (selector.includes(',')) {
                        selector = selector.split(',');
                        selector.forEach((item) => {
                            ret.push('.darkmode ' + item.trim() + '{' + darkRules.join(';') + '}');
                        })
                    } else {
                        ret.push('.darkmode ' + selector + '{' + darkRules.join(';') + '}');
                    }
                    cssEndIndex = src.indexOf('}', nameEnd);
                }
            } else {
                break;
            }
        }
        if (ret.length > 0) {
            // 将暗黑模式和夜晚模式加入文件
            src = src.substring(0, cssEndIndex + 1) + dropDuplicate(ret).join('') + src.substring(cssEndIndex + 1, src.length - 1);
            // 将文件中的颜色列表进行替换
            for (let colorReg of matchColorRegs) {
                let color = (colorReg + '').substring(12, (colorReg + '').length - 14);

                src = src.replace(colorReg, function (match, p1, p2, p3) {
                    return p1 + themeColor[color].default + p3;
                });
            }
        }
        return src;

        // 查找css尾部，兼容 @keyframes {10%{...}}
        function findCssEnd(src, start) {
            var level = 1
            var cssEnd = start
            while (true) {
                cssEnd++
                var char = src[cssEnd]
                if (!char) {
                    return -1
                }
                else if (char === '{') {
                    level++
                } else if (char === '}') {
                    level--
                    if (level === 0) {
                        break
                    }
                }
            }
            return cssEnd
        }
    }
    this.getRules = function (cssCode) {
        var rules = cssCode.split(';')
        var ret = [];
        var colorReg;
        rules.forEach(rule => {         
            colorReg = this.testCssCode(rule + ';');
            if (colorReg) {
                colorReg = (colorReg + '').substring(12, (colorReg + '').length-14);
                var retObj = {};
                retObj[colorReg] = rule.replace(SpaceReg, ' ');
                ret.push(retObj);
            }
        })
        return ret
    }
    // 判断是否匹配颜色列表
    this.testCssCode = function (cssCode) {
        var exist;
        for (var colorReg of matchColorRegs) {
            
            exist = cssCode.match(colorReg);
            if (exist) {
                return colorReg;
            }
        }
        return false
    }
}
// 去重
function dropDuplicate(arr) {
    var map = {}
    var r = []
    for (var s of arr) {
        if (!map[s]) {
            r.push(s)
            map[s] = 1
        }
    }
    return r
}
